<?php

namespace s94\wechat;

/**
 * 微信公众号素材管理
 */
class Material extends Base
{
    public static $typeMap = [
        'image'=>'图片',
        'voice'=>'语音',
        'video'=>'视频',
        'thumb'=>'缩略图',
        'news'=>'图文',
    ];

    private static function res($res){
        if (is_string($res)){
            $arr = explode("\r\n\r\n", $res, 2);
            $res = json_decode($arr[1], true);
        }
        return $res;
    }

    public function add($file, $video_title='', $video_info='')
    {
        if (is_string($file)){
            $file = CurlFileData::getFromPath($file);
        }
        self::assert($file instanceof CurlFileData, 'file参数必须为CurlFileData类型对象');

        $type = explode('/', $file->getMime())[0];
        if ($type=='audio') $type = 'voice';
        self::assert(in_array($type, ['image','voice','video','thumb']), '素材类型错误');

        $data = ['media'=> $file];
        if ($type=='video'){
            $video_title = $video_title ?: $file->getName(); //标题不能为空
            $video_title = substr($video_title, -30);
            $data['description'] = json_encode(['title'=>$video_title, 'introduction'=>$video_info], JSON_UNESCAPED_UNICODE);
        }
        $res = $this->apiSdk('cgi-bin/material/add_material',['access_token'=>$this->accessToken(),'type'=>$type], $data);
        //上传接口响应body可能包含了头消息，需要特殊处理
        if (is_string($res)){
            $arr = explode("\r\n\r\n", $res, 2);
            $res = json_decode($arr[1], true);
        }
        return $res;
    }

    /**上传永久素材
     * @param string|array $file 上传的文件，可以为文件路径(string)，或者array格式：['path'=>'文件路径','name'=>'文件名','type'=>'MIME类型']
     * @param string $type 素材类型，传入空表示根据文件路径的后缀名计算
     * @param string $video_title 视频素材的视频标题
     * @param string $video_info 视频素材的视频介绍
     * @return array 格式：["media_id"=>MEDIA_ID,"url"=>URL]
     * @throws SdkException
     */
    public function upload($file, $type='', $video_title='', $video_info='')
    {
        $mime_map = [
            'bmp'=>'image/bmp','png'=>'image/png','jpeg'=>'image/jpeg','jpg'=>'image/jpeg','gif'=>'image/gif',
            'mp3'=>'audio/mpeg','wma'=>'audio/wma','wav'=>'audio/wav','amr'=>'audio/amr',
            'mp4'=>'video/mp4',
        ];
        if (is_string($file)) $file = ['path'=>$file];
        self::assert($file['path'],'文件路径不能为空');
        if (empty($file['type'])){
            $i = strrpos($file['path'], '.');
            $suffix = $i ? substr($file['path'], $i+1) : '';
            $file['type'] = $suffix ? ($mime_map[strtolower($suffix)] ?? '') : '';
        }
        if (!$type && $file['type']){
            $type = explode('/', $file['type'])[0];
            if ($type=='audio') $type = 'voice';
        }
        self::assert($type && in_array($type, ['image','voice','video','thumb']), '素材类型错误');
        $curl_file = new CurlFileData($file['name'], null, $file['type']);
        $curl_file->setContent(file_get_contents($file['path']));
        $data = ['media'=> $curl_file];
        if ($type=='video'){
            $data['description'] = json_encode(['title'=>$video_title, 'introduction'=>$video_info], JSON_UNESCAPED_UNICODE);
        }
        $res = $this->apiSdk('cgi-bin/material/add_material',['access_token'=>$this->accessToken(),'type'=>$type], $data);
        //上传接口响应body可能包含了头消息，需要特殊处理
        if (is_string($res)){
            $arr = explode("\r\n\r\n", $res, 2);
            $res = json_decode($arr[1], true);
        }
        return $res;
    }

    /**上传图文消息内的图片获取URL
     * @param string|CurlFileData $file 上传的文件，可以为文件路径(string)，或者CurlFileData对象
     * @return array 格式：['url'=>图片网络地址]
     * @throws SdkException
     */
    public function uploadimg($file)
    {
        if (is_string($file)){
            $file = CurlFileData::getFromPath($file);
        }
        self::assert($file instanceof CurlFileData, 'file参数必须为CurlFileData类型对象');
        $mime_map = [
            'bmp'=>'image/bmp','png'=>'image/png','jpeg'=>'image/jpeg','jpg'=>'image/jpeg','gif'=>'image/gif',
        ];
        self::assert(in_array($file->getMime(), $mime_map),'文件类型错误：'.$file->getMime());
        $data = ['media'=> $file];
        $res = $this->apiSdk('cgi-bin/media/uploadimg',['access_token'=>$this->accessToken()], $data);
        //上传接口响应body可能包含了头消息，需要特殊处理
        if (is_string($res)){
            $arr = explode("\r\n\r\n", $res, 2);
            $res = json_decode($arr[1], true);
        }
        return $res;
    }

    /**
     * @param string $type 素材类型
     * @param int $offset 偏移位置，默认为0
     * @param int $count 返回素材的数量，取值在1到20之间
     * @return array 格式：['count'=>素材总数, 'list'=>[['media_id'=>'素材id','name'=>'素材名','update_time'=>'更新时间','url'=>'素材链接','news_item'=>'图文项目列表'],...]]
     * @throws \Exception
     */
    public function list($type, $offset=0, $count=20)
    {
        self::assert(in_array($type, array_keys(self::$typeMap)), '素材类型错误');
        self::assert($count<=20 && $count>0, '每页数量限制为1-20');
        $post_data = [
            'type'=> $type,
            'offset'=> $offset,
            'count'=> $count,
        ];
        $res = $this->apiSdk('cgi-bin/material/batchget_material',['access_token'=>$this->accessToken()], json_encode($post_data, JSON_UNESCAPED_UNICODE));
        $list = $res['item'];
        if ($type=='news'){
            foreach ($list as &$row){
                $news_item = $row['content']['news_item'];
                unset($row['content']);
                $row['news_item'] = $news_item;
                $row['name'] = $news_item[0]['title'];
                $row['url'] = $news_item[0]['url'];
            }
        }
        return [
            'count'=> $res['total_count'],
            'list'=> $list,
        ];
    }

    /**素材详情
     * @param string $media_id 素材id
     * @return string|array 图文素材返回图文项目列表格式：[['title','thumb_media_id','show_cover_pic','author','digest','content','url','content_source_url'],...]，
     * 视频素材返回格式：['title','description','down_url']，
     * 其他素材直接返回文件二进制字符串
     * @throws SdkException
     */
    public function info($media_id)
    {
        $post_data = ['media_id'=>$media_id];
        $res = $this->apiSdk('cgi-bin/material/get_material',['access_token'=>$this->accessToken()], json_encode($post_data, JSON_UNESCAPED_UNICODE));
        if (is_array($res) && isset($res['news_item'])){
            return $res['news_item'];
        }
        return $res;
    }

    /**删除永久素材
     * @param string $media_id 素材id
     * @return mixed
     * @throws SdkException
     */
    public function delete($media_id)
    {
        $post_data = ['media_id'=>$media_id];
        $res = $this->apiSdk('cgi-bin/material/del_material',['access_token'=>$this->accessToken()], json_encode($post_data, JSON_UNESCAPED_UNICODE));
        return $res;
    }

    public function count()
    {
        $res = $this->apiSdk('cgi-bin/material/get_materialcount',['access_token'=>$this->accessToken()]);
        return $res;
    }
}